package org.zjx.util;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Robot操作工具类 - 线程安全版本
 */
@Slf4j
public class RobotUtil {
    @Getter
    public enum MouseAction {
        UP("鼠标抬起"),
        DOWN("鼠标按下");

        private final String suffix;

        MouseAction(String suffix) {
            this.suffix = suffix;
        }
    }

    public static final int MOUSE_LEFT = InputEvent.BUTTON1_DOWN_MASK;
    public static final int MOUSE_RIGHT = InputEvent.BUTTON3_DOWN_MASK;

    private static volatile RobotUtil instance;
    private final Robot robot;
    private final Lock operationLock = new ReentrantLock(true); // 公平锁

    private RobotUtil() throws AWTException {
        this.robot = new Robot();
        this.robot.setAutoDelay(10);
        this.robot.setAutoWaitForIdle(true);
    }

    public static RobotUtil getInstance() {
        if (instance == null) {
            synchronized (RobotUtil.class) {
                if (instance == null) {
                    try {
                        instance = new RobotUtil();
                    } catch (AWTException e) {
                        throw new RuntimeException("初始化 Robot 失败", e);
                    }
                }
            }
        }
        return instance;
    }

    /**
     * 原子性操作：移动并点击
     */
    public void moveAndClick(Point point, int button) {
        operationLock.lock();
        try {
            internalMoveMouse(point.x, point.y);
            internalDelay(30);
            internalClickMouse(button);
        } finally {
            operationLock.unlock();
        }
    }

    /**
     * 原子性操作：拖拽
     */
    public void atomicDrag(int startX, int startY, int endX, int endY) {
        operationLock.lock();
        try {
            internalMoveMouse(startX, startY);
            internalMousePress(MOUSE_LEFT);
            internalDelay(100);
            internalMoveMouse(endX, endY);
            internalDelay(100);
            internalMouseRelease(MOUSE_LEFT);
        } finally {
            operationLock.unlock();
        }
    }

    /**
     * 复合操作：移动鼠标到指定点并点击（原子操作）
     */
    public void clickMouse(Point point) {
        moveAndClick(point, 1);
    }

    /**
     * 复合操作：点击鼠标（原子操作）
     */
    public void clickMouse(int button) {
        operationLock.lock();
        try {
            internalClickMouse(button);
        } finally {
            operationLock.unlock();
        }
    }

    // 内部方法 - 不需要单独加锁，由外部方法保证线程安全
    private void internalMoveMouse(int x, int y) {
        robot.mouseMove(x, y);
        internalDelay(10);
    }

    private void internalClickMouse(int button) {
        int mouseButton = button == 1 ? MOUSE_LEFT : MOUSE_RIGHT;
        internalMousePress(mouseButton);
        internalDelay(50);
        internalMouseRelease(mouseButton);
    }

    private void internalMousePress(int button) {
        robot.mousePress(button);
        internalDelay(10);
    }

    private void internalMouseRelease(int button) {
        log.debug("[Robot] 鼠标释放: 按钮={}", button);
        robot.mouseRelease(button);
        internalDelay(10);
    }

    private void internalDelay(int millis) {
        if (millis <= 0) return;
        try {
            // 使用robot的delay而不是Thread.sleep，保持操作序列性
            robot.delay(millis);
        } catch (Exception e) {
            log.warn("[Robot] 延迟异常", e);
        }
    }

    // 原有的独立操作方法（保持向后兼容）
    public void moveMouse(int x, int y) {
        operationLock.lock();
        try {
            internalMoveMouse(x, y);
        } finally {
            operationLock.unlock();
        }
    }

    public void clickMouse(int button, MouseAction action) {
        operationLock.lock();
        try {
            int mouseButton = button == 1 ? MOUSE_LEFT : MOUSE_RIGHT;
            if (action == MouseAction.DOWN) {
                internalMousePress(mouseButton);
            } else {
                internalMouseRelease(mouseButton);
            }
        } finally {
            operationLock.unlock();
        }
    }

    public void dragMouse(int startX, int startY, int endX, int endY) {
        atomicDrag(startX, startY, endX, endY);
    }

    // 其他方法保持不变...
    public BufferedImage getImage(Rectangle rectangle) {
        operationLock.lock();
        try {
            return robot.createScreenCapture(rectangle);
        } finally {
            operationLock.unlock();
        }
    }

    public void write(String text) {
        operationLock.lock();
        try {
            for (char c : text.toCharArray()) {
                int keyCode = KeyEvent.getExtendedKeyCodeForChar(c);
                if (KeyEvent.CHAR_UNDEFINED == keyCode) {
                    log.warn("[Robot] 无法识别的字符: {}", c);
                    continue;
                }
                try {
                    robot.keyPress(keyCode);
                    robot.keyRelease(keyCode);
                    internalDelay(20);
                } catch (IllegalArgumentException e) {
                    log.warn("[Robot] 无法输入字符: {}", c);
                }
            }
        } finally {
            operationLock.unlock();
        }
    }

    public void pressKeyCombination(int... keyCodes) {
        operationLock.lock();
        try {
            for (int keyCode : keyCodes) {
                robot.keyPress(keyCode);
            }
            internalDelay(100);
            for (int keyCode : keyCodes) {
                robot.keyRelease(keyCode);
            }
        } finally {
            operationLock.unlock();
        }
    }
}